package retriever;
import java.io.IOException;
import java.net.URL;
import java.util.Observable;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/**
 * This class gets a web page via a URL from the PageToRetrieve
 * queue, and then inserts it into a PageBuffer queue for the page
 * parser to process.
 * 
 * @author Zach Turk, Dickson Kwong, Stephen Amos
 */
public class PageRetriever extends Observable implements Runnable{
	/**
	 * The URL to be processed.
	 */
	private URL my_url;

	/**
	 * The document containing the source code at the specified URL.
	 */
	private Document my_source;

	/**
	 * The queue containing the source code of the provided URL.
	 */
	private BlockingQueue<Document> my_queue;

	/**
	 * The collection of URLs.
	 */
	private BlockingQueue<URL> my_urls;
	
	/**
	 * The amount of pages all retrievers have retrieved.
	 */
	private int my_total_pages_retrieved;

	/**
	 * The amount of URLs found at this link.
	 */
	private int my_url_count = 0;
	
	/**
	 * This constructor creates a PageRetriever object based upon
	 * the URL address passed in.
	 * 
	 * @param the_url The URL that this PageRetriever object is to
	 * process.
	 * @param the_queue The queue of URL links to be retrieved.
	 * @param the_visited The collection of links that have been visited.
	 * 
	 * THIS METHOD IS UNDER CONSTRUCTION.
	 */
	public PageRetriever(BlockingQueue<URL> the_urls, BlockingQueue<Document> the_queue) {
		my_urls = the_urls;
		my_queue = the_queue;
	}
	
	/**
	 * Loads the next URL.
	 */
	private void loadURL() {
		try {
			my_url = my_urls.take();
		} catch (InterruptedException e) { }
	}
	
	/**
	 * Pulls source from the current URL
	 */
	private void getSource() {
		try {
			my_source = Jsoup.connect(my_url.toString()).get();
		} catch (Exception e) { }
	}
	
	/**
	 * Adds a new page to my_queue.
	 */
	private void addPage() {
		if (my_source == null) return;
		try {
			my_queue.put(my_source);
		} catch(InterruptedException e) { }
	}
	
	/**
	 * Returns the total pages retrieved from every possible page retriever.
	 * @return the total pages retrieved from every possible page retriever.
	 */
	public int getTotalPagesRetrieved()
	{
		return my_total_pages_retrieved;
	}

	/**
	 * This retrieves the web page at the specified URL of this PageRetriever
	 * object.
	 * 
	 * @return The source code of the specified web page URL.
	 */
	public void run() {
		loadURL();
		getSource();
		addPage();
		setChanged();
		notifyObservers();
	}
	
}
